package com.ruoyi.web.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.framework.web.exception.TadpoleException;
import com.ruoyi.web.domain.VipDepositDetail;
import com.ruoyi.web.dto.VipDepositDetailAddDTO;
import com.ruoyi.web.dto.VipDepositDetailConditionDTO;
import com.ruoyi.web.dto.VipDepositDetailEditDTO;
import com.ruoyi.web.enums.VipDepositDetailEnum;
import com.ruoyi.web.mapper.UserCapitalMapper;
import com.ruoyi.web.mapper.VipDepositDetailMapper;
import com.ruoyi.web.service.IVipDepositDetailService;
import com.ruoyi.web.utils.CommonUtil;
import com.ruoyi.web.utils.MysqlUtil;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * vip押金明细Service业务层处理
 *
 * @since 2023-03-26
 */
@Service
@AllArgsConstructor
public class VipDepositDetailServiceImpl implements IVipDepositDetailService {

    private final VipDepositDetailMapper vipDepositDetailMapper;
    private final UserCapitalMapper userCapitalMapper;
    private final CommonUtil commonUtil;
    private final MysqlUtil mysqlUtil;

    /**
     * 查询vip押金明细
     *
     * @param id vip押金明细主键
     * @return vip押金明细
     */
    @Override
    public VipDepositDetail selectVipDepositDetailById(Long id) {
        return vipDepositDetailMapper.selectVipDepositDetailById(id);
    }

    /**
     * 分页查询
     *
     * @param condition 查询条件
     * @return {@link List< VipDepositDetail>}
     * @since 2023/3/27 15:39
     */
    @Override
    public List<VipDepositDetail> selectVipDepositDetailList(VipDepositDetailConditionDTO condition) {
        List<VipDepositDetail> list = vipDepositDetailMapper.selectVipDepositDetailList(condition);

        list.forEach(i -> {
            i.setStatus(VipDepositDetailEnum.Status.findName(i.getStatus()));
        });

        return list;
    }

    /**
     * 新增
     *
     * @param dto dto
     * @since 2023/3/27 14:08
     */
    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void insertVipDepositDetail(VipDepositDetailAddDTO dto) {
        VipDepositDetail detail = BeanUtil.copyProperties(dto, VipDepositDetail.class);
        detail.setEndTime(getEndTime(detail.getStartTime(), detail.getExpireDay()));
        detail.setStatus(VipDepositDetailEnum.Status.CAN_NOT.getValue());
        commonUtil.initCreateAbout(detail);
        if (vipDepositDetailMapper.insertVipDepositDetail(detail) != 1) {
            throw new TadpoleException();
        }

        // 资金账户增加VIP押金额度
        if (userCapitalMapper.addVipDeposit(detail.getUserId(), detail.getAmount()) != 1) {
            throw new TadpoleException();
        }
    }

    /**
     * 计算结束时间
     *
     * @param startTime 开始时间
     * @param expireDay 过期天数
     * @return {@link Date}
     * @since 2023/3/27 14:27
     */
    private static Date getEndTime(Date startTime, int expireDay) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startTime);
        calendar.add(Calendar.DATE, expireDay);
        return calendar.getTime();
    }

    /**
     * 修改
     *
     * @param dto dto
     * @since 2023/3/27 14:21
     */
    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void updateVipDepositDetail(VipDepositDetailEditDTO dto) {
        VipDepositDetail oldDetail = new VipDepositDetail();
        oldDetail.setId(dto.getId());
        oldDetail = vipDepositDetailMapper.getOneLock(oldDetail);
        if (Objects.isNull(oldDetail)
                || !VipDepositDetailEnum.Status.CAN_NOT.getValue().equals(oldDetail.getStatus())) {
            throw new TadpoleException("数据状态已发生改变，请刷新重试");
        }

        oldDetail.setStartTime(dto.getStartTime());
        oldDetail.setExpireDay(dto.getExpireDay());
        oldDetail.setEndTime(getEndTime(oldDetail.getStartTime(), oldDetail.getExpireDay()));
        oldDetail.setRemark(dto.getRemark());

        // 计算金额差额
        BigDecimal amountDifference = dto.getAmount().subtract(oldDetail.getAmount());
        oldDetail.setAmount(dto.getAmount());
        commonUtil.initUpdateAbout(oldDetail);

        // 修改资金账户
        if (amountDifference.compareTo(BigDecimal.ZERO) > 0
                && userCapitalMapper.addVipDeposit(dto.getUserId(), amountDifference) != 1
                || amountDifference.compareTo(BigDecimal.ZERO) < 0
                && userCapitalMapper.minusVipDeposit(dto.getUserId(), amountDifference.abs()) != 1) {
            throw new TadpoleException();
        }

        // 修改押金明细
        if (vipDepositDetailMapper.updateVipDepositDetail(oldDetail) != 1) {
            throw new TadpoleException();
        }
    }

    /**
     * 批量删除vip押金明细
     *
     * @param ids 需要删除的vip押金明细主键
     * @return 结果
     */
    @Override
    public void deleteVipDepositDetailByIds(Long[] ids) {
        for (Long id : ids) {
            try {
                mysqlUtil.startLocalTx();

                // 根据id查询
                VipDepositDetail oldDetail = new VipDepositDetail();
                oldDetail.setId(id);
                oldDetail = vipDepositDetailMapper.getOneLock(oldDetail);
                if (Objects.isNull(oldDetail)
                        || !VipDepositDetailEnum.Status.CAN_NOT.getValue().equals(oldDetail.getStatus())) {
                    throw new TadpoleException("数据状态已发生改变，请刷新重试");
                }

                // 修改资金账户
                if (userCapitalMapper.minusVipDeposit(oldDetail.getUserId(), oldDetail.getAmount()) != 1) {
                    throw new TadpoleException();
                }

                // 逻辑删除明细
                commonUtil.initUpdateAbout(oldDetail);
                if (vipDepositDetailMapper.logicDelete(oldDetail) != 1) {
                    throw new TadpoleException();
                }

                mysqlUtil.commitLocalTx();

            } catch (Throwable e) {
                mysqlUtil.rollbackLocalTx();
            }
        }
    }
}
